#include<iostream>
#include<unistd.h>
#include<signal.h>
using namespace std;

void PrintPending(sigset_t &pending)
{
    for(int signo=31;signo >= 1;signo--)
    {
        if(sigismember(&pending,signo))
        {
            cout<<"1";
        }
        else
        {
            cout<<"0";
        }
    }
    cout<<endl;
}

void handler(int signo)
{
    cout<<"catch a signo"<<signo<<endl;
}

int main()
{
    //0.对二号信号捕捉
    signal(2,handler);
    //1.先对二号信号进行屏蔽   --- 数据预备
    sigset_t bset,oset;      //在用户栈上开辟的空间，属于用户区

    sigemptyset(&bset);//清空信号集
    sigemptyset(&oset);

    sigaddset(&bset,2);//添加二号信号，此时只是在用户层定义了一个变量
                        //此时没有进入到进程的task_struct
    
    //1.2 调用系统调用，将数据设置进内核
    sigprocmask(SIG_SETMASK,&bset,&oset);//设置新的位图，保存老的位图
                        //此时已经把二号信号屏蔽了

    //2.重复打印当前进程的pending集 00000000000000000000000000
    sigset_t pending;
    int cnt =0;
    while(true)
    {
        //2.1 获取
        int n = sigpending(&pending);
        if(n<0) continue;
        //2.2 打印
        PrintPending(pending);
        sleep(1); 
        cnt++;
        //2.3 解除阻塞
        if(cnt == 20)
        {
            cout<<"unblock 2 signo"<<endl;
            sigprocmask(SIG_SETMASK,&oset,nullptr);//把老的信号屏蔽字设置回去
        }

    }

    //3 发送二号信号 0000000000000000010

    return 0;
}